package net.pws.oos.web;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import net.pws.common.util.DateUtils;
import net.pws.common.util.StringUtils;
import net.pws.common.jackson.JsonUtils;
import net.pws.common.persistence.EntityManager;
import net.pws.oos.biz.model.Notice;
import net.pws.oos.biz.model.User;
import net.pws.oos.biz.query.NoticeFinder;
import net.pws.oos.biz.query.SystemManageFinder;
import net.pws.oos.biz.query.parameter.NoticeQueryParameter;
import net.pws.oos.biz.service.NoticeService;
import net.pws.oos.security.SecurityUtils;
import net.pws.oos.web.dto.NoticeDto;
import net.pws.oos.web.dto.NoticeNewDto;
import net.pws.oos.web.dto.NoticeReceiverDto;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/biz/notice")
@SuppressWarnings("rawtypes")
public class NoticeAction {
    
    private final transient Log logger = LogFactory.getLog(NoticeAction.class);
    
    @Autowired
    private EntityManager entityManager;
    
    @Autowired
    private NoticeService noticeService;
    
    @Autowired
    private NoticeFinder noticeFinder;
    
    @Autowired
    private SystemManageFinder systemManageFinder;
    
    @RequestMapping("/edit.do")
    public String editPage(ModelMap map) {
        return "notice/new";
    }
    
    @RequestMapping("/detail.do")
    public String detailPage(ModelMap map) {
        return "notice/detail";
    }
    
    @RequestMapping("/detail.json")
    @ResponseBody
    public Object getNotice(String id) {
        try {
            Notice notice = noticeFinder.getNotice(id);
            NoticeDto dto = NoticeDto.from(notice);
            List<Map> receivers = noticeFinder.listReceivers(id);
            List<NoticeReceiverDto> readReceivers = new ArrayList<NoticeReceiverDto>();
            List<NoticeReceiverDto> unreadReceivers = new ArrayList<NoticeReceiverDto>();
            dto.setReadReceivers(readReceivers);
            dto.setUnreadReceivers(unreadReceivers);
            for (Map map : receivers) {
                NoticeReceiverDto receiverDto = NoticeReceiverDto.from(map);
                if (receiverDto.getReadDate() == null) {
                    unreadReceivers.add(receiverDto);
                }
                else {
					readReceivers.add(receiverDto);
                }
            }
            return JsonUtils.succeedMap(dto);
        }
        catch (Exception e) {
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/delete.json")
    @ResponseBody
    public Object deleteNotice(String id) {
        try {
        	noticeService.delete(id);
        	return JsonUtils.succeedMap(id);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/save.json")
    @ResponseBody
    public Object saveNotice(NoticeNewDto dto) {
        try {
            Notice notice = createNotice(dto);
            return JsonUtils.succeedMap(notice.getId());
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    private Notice createNotice(NoticeNewDto dto) {
        Notice notice = NoticeDto.to(dto);
        notice.setCreateDate(new Date());
        User creator = entityManager.find(User.class,
                                          SecurityUtils.currentUserId());
        notice.setCreator(creator);
        notice.setOrgan(creator.getOrganization());
        
        String organs = dto.getReceiveOrgans();
        String users = dto.getReceivers();
        Set<User> receivers = new HashSet<User>();
        if (StringUtils.isNotBlank(organs)) {
            String[] organArray = organs.split(",");
            for (String organId : organArray) {
                receivers.addAll(systemManageFinder.getUserListByOrganTree(organId));
            }
        }
        receivers.addAll(systemManageFinder.getUserList(StringEscapeUtils.escapeSql(users)));
        return noticeService.create(notice, receivers);
    }
    
    /**
     * 列表页
     * 
     * @return
     */
    @RequestMapping("/list.do")
    public String listPage(ModelMap map) {
        Date today = new Date();
        Date firstDay = DateUtils.getFirstDay();
        String startDate = DateUtils.getDateStr(firstDay);
        String endDate = DateUtils.getDateStr(today);
        map.put("createStartDate", startDate);
        map.put("createEndDate", endDate);
        return "notice/list";
    }
    
    @RequestMapping("/list.json")
    @ResponseBody
    public Object list(NoticeQueryParameter queryParameter) {
        queryParameter = initByRole(queryParameter);
        try {
            List<Map> list = noticeFinder.list(queryParameter);
            return JsonUtils.succeedMap(NoticeDto.from(list));
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/count.json")
    @ResponseBody
    public Object count(NoticeQueryParameter queryParameter) {
        queryParameter = initByRole(queryParameter);
        try {
            int count = noticeFinder.count(queryParameter);
            return JsonUtils.succeedMap(count);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    private NoticeQueryParameter initByRole(NoticeQueryParameter queryParameter) {
        if (queryParameter == null) {
            queryParameter = new NoticeQueryParameter();
        }
        if (StringUtils.areBlank(queryParameter.getOrganId(),
                                 queryParameter.getCreatorId())) {
            queryParameter.setOrganId(SecurityUtils.currentUser().getOrganId());
        }
        
        return queryParameter;
    }
    
    /**
     * 列表页
     * 
     * @return
     */
    @RequestMapping("/myList.do")
    public String myListPage(ModelMap map) {
        Date today = new Date();
        Date firstDay = DateUtils.getFirstDay();
        String startDate = DateUtils.getDateStr(firstDay);
        String endDate = DateUtils.getDateStr(today);
        map.put("createStartDate", startDate);
        map.put("createEndDate", endDate);
        return "notice/my_list";
    }
    
    @RequestMapping("/myList.json")
    @ResponseBody
    public Object myList(NoticeQueryParameter queryParameter) {
        queryParameter.setReceiverId(SecurityUtils.currentUserId());
        try {
            List<Map> maps = noticeFinder.myList(queryParameter);
            return JsonUtils.succeedMap(NoticeDto.from(maps));
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }

    
    @RequestMapping("/myCount.json")
    @ResponseBody
    public Object myCount(NoticeQueryParameter queryParameter) {
        queryParameter.setReceiverId(SecurityUtils.currentUserId());
        try {
            int count = noticeFinder.myCount(queryParameter);
            return JsonUtils.succeedMap(count);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }

    @RequestMapping("/read.do")
    public String readPage(ModelMap map) {
        return "notice/read";
    }
    
    @RequestMapping("/read.json")
    @ResponseBody
    public Object readNotice(String id) {
        try {
            Notice notice = noticeFinder.getNotice(id);
            NoticeDto dto = NoticeDto.from(notice);
            noticeService.read(id, SecurityUtils.currentUserId());
            return JsonUtils.succeedMap(dto);
        }
        catch (Exception e) {
            return JsonUtils.failedMap(e.getMessage());
        }
    }
}
